﻿/**
 *@description:
 *@file: sprite_renderer.cpp
 *@author: snow-tyan
 *@email: zziywang@163.com
 *@date: 31 January 2023
 *@copyright: 2018-2022 AiRiA. All rights reserved.
 */

#include "mygl/sprite_renderer.h"
#include "mygl/shader.h"
#include "mygl/texture2d.h"

namespace mygl {

SpriteRenderer::SpriteRenderer(std::shared_ptr<Shader> shader)
    : shader_(shader), quad_vao_(0) {
  initRenderData();
}

SpriteRenderer::~SpriteRenderer() {
  if (quad_vao_ != 0) {
    glDeleteVertexArrays(1, &quad_vao_);
  }
}

void SpriteRenderer::DrawSprite(std::shared_ptr<Texture2D> texture2d, glm::vec2 position,
                                glm::vec2 size, GLfloat rotate_angle, glm::vec3 color) {
  glm::mat4 model(1.0f);
  model = glm::translate(model, glm::vec3(position, 0.0f));

  // 将四边形移动到原图形中心点（旋转原点移动到四边形的中心）
  model = glm::translate(model, glm::vec3(0.5f * size.x, 0.5f * size.y, 0.0f));
  // 所有2d都是绕z轴，绕z轴旋转若干角度（弧度制）
  model = glm::rotate(model, glm::radians(rotate_angle), glm::vec3(0.0f, 0.0f, 1.0f));
  // 复原四边形的位置
  model = glm::translate(model, glm::vec3(-0.5f * size.x, -0.5f * size.y, 0.0f));

  model = glm::scale(model, glm::vec3(size, 1.0f));

  shader_->UseProgram();
  shader_->SetUniformMat4Float("model", model);
  shader_->SetUniformVec3Float("sprite_color", color);
  glActiveTexture(GL_TEXTURE0);
  texture2d->Bind();

  glBindVertexArray(quad_vao_);
  glDrawArrays(GL_TRIANGLES, 0, 6);
  glBindVertexArray(0);  // Unbind
}

void SpriteRenderer::initRenderData() {
  // 四边形，以
#if 0
  GLfloat vertices[] = {
// 位置      // 纹理
///!NOTE: 开启面剔除+正射投影颠倒，只显示逆时针顶点
      1.0f, 1.0f, 1.0f, 1.0f,  // 右上
      1.0f, 0.0f, 1.0f, 0.0f,  // 右下
      0.0f, 1.0f, 0.0f, 1.0f,  // 左上

      1.0f, 0.0f, 1.0f, 0.0f,  // 右下
      0.0f, 0.0f, 0.0f, 0.0f,  // 左下
      0.0f, 1.0f, 0.0f, 1.0f,  // 左上
#endif
  GLfloat vertices[] = {
      0.0f, 1.0f, 0.0f, 1.0f,  //
      1.0f, 0.0f, 1.0f, 0.0f,  //
      0.0f, 0.0f, 0.0f, 0.0f,

      0.0f, 1.0f, 0.0f, 1.0f,  //
      1.0f, 1.0f, 1.0f, 1.0f,  //
      1.0f, 0.0f, 1.0f, 0.0f,
  };
  GLuint vbo;
  glGenVertexArrays(1, &quad_vao_);
  glGenBuffers(1, &vbo);

  glBindVertexArray(quad_vao_);
  glBindBuffer(GL_ARRAY_BUFFER, vbo);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void *)0);
  glEnableVertexAttribArray(0);
  // Unbind
  glBindBuffer(GL_ARRAY_BUFFER, 0);
  glBindVertexArray(0);
}

}  // namespace mygl
